# -*- coding: utf-8 -*-

# -----------------单连接--------------------------

# from elasticsearch import Elasticsearch
# es = Elasticsearch(hosts="127.0.0.1:9200")

# -----------------集群连接--------------------------

from elasticsearch_dsl import connections
from elasticsearch_dsl import Search
from elasticsearch_dsl import Q

class QueryElastcisearch:
    """
    可以独立部署，参数可以通过传递来进行查询，
    或者通过RPC来实现也可以
    再或者通过分布式队列等待
    query 支持被覆盖
    s.query = Q('bool', must=[Q('match', title='python'), Q('match', body='best')])
    """

    def __init__(self,index=None):
        self.index= index
        self.es = connections.create_connection(hosts=['localhost:9200','localhost:9201'], timeout=60)

    def __client(self):
        return Search(using=self.es)

    def match_query(self,**kwargs):
        # @params:kwargs:
        """
        {
            "fields1":"data1",
            "fields2":"data2"
        }
        """
        # 单匹配
        #  title 是要匹配的字段，对应的值就是要搜索的结果
        # kwargs == {'fields':"查询的值value"}， match 是匹配的方法
        s = self.__client().query("match",**kwargs)
        return s
    
    def multi_match_query(self,**kwargs):
        # @params:kwargs 参数格式同上
        # 多匹配的对象
        __query_dict = {}
        for v in kwargs.values():
            __query_dict.update({
                "multi_match":{
                    "query":"{}".format(v),
                    "fields":kwargs.keys()
                }
            })
        return Q(**__query_dict)
    def return_search(self,query):
        # @params:query 查询的对象
        # execute()就是开始执行搜索的方法
        response = query.params(size=10000).execute()
        return response
    
    def match_hit(self,query):
        # @params:query 查询的对象
        return [i for i in query]

    def match_serializer(self,query):
        # @params:query 查询的对象
        # 序列化结果
        return query.to_dict()

    def delete_index(self,query):
        # @params:query 查询的对象
        # 查询删除
        return query.delete()


class TermSearch(QueryElastcisearch):

    """
    支持一些 更方便的查询
    s = Search()
    s = s.filter('term', category__keyword='Python')
    s = s.query('match', address__city='prague')

    或者使用
    s = Search()
    s = s.filter('term', **{'category.keyword': 'Python'})
    s = s.query('match', **{'address.city': 'prague'})

    查询组合
    可以使用逻辑运算符组合查询对象：
    Q("match", title='python') | Q("match", title='django')
    # {"bool": {"should": [...]}}

    Q("match", title='python') & Q("match", title='django')
    # {"bool": {"must": [...]}}

    ~Q("match", title="python")
    # {"bool": {"must_not": [...]}}

    当.query()多次调用该方法时，&将在内部使用该运算符：

    s = s.query().query()
    print(s.to_dict())
    # {"query": {"bool": {...}}}
    
    如果要对查询表单进行精确控制，使用Q快捷方式直接构造组合查询：

    q = Q('bool',
        must=[Q('match', title='python')],
        should=[Q(...), Q(...)],
        minimum_should_match=1
    )
    s = Search().query(q)

    # start_time为开始时间，end_time为结束时间
    q = Q('bool', must=[Q('range', start_time={"gte": start_time}), Q('range', end_time={"lte": end_time})])
    s = Search().query(q)

    """
